<!--
    文件名: rollCall_demo_v2.html
    描述: 这是一个学生随机点名程序，用于随机选择学生进行点名。
    作者: 周雪松
    创建日期: 2025-01-25
    修改日期: 2025-01-26
-->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>学生随机点名</title>
    <style>
        table {
            width: 100%;
            border-collapse: collapse;
            margin-bottom: 20px;
        }
        th, td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: center;
        }
        th {
            background-color: #f2f2f2;
        }
        .selected {
            background-color: #FFF000; /* 背景颜色 */
            font-weight: bold; /* 文本加粗 */
            color: #FF0000; /* 字体颜色为红色 */
        }
        #studentName {
            font-size: 24px;
            font-weight: bold;
            margin-bottom: 20px;
        }

        /* 默认按钮样式 */
        .button {
            background-color: #4CAF50; /* 绿色背景 */
            color: white; /* 白色文字 */
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }

        /* 禁用状态下的按钮样式 */
        .button.disabled {
            background-color: #cccccc; /* 灰色背景 */
            cursor: not-allowed; /* 禁用鼠标指针 */
        }


        /* 使用 flexbox 布局让按钮居中 */
        .button-container {
            display: flex;
            justify-content: center;
        }

        /* 调整按钮的宽度和高度 */
        #studentPicker {
            width: 160px;
            height: 80px;
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
        }
    </style>
</head>
<body>
<div>
    <div id="studentName"></div>
    <table>
        <thead>
        <tr>
            <th colspan="10">学生名单</th>
        </tr>
        </thead>
        <tbody id="studentTableBody"></tbody>
    </table>
    <!-- 添加一个类名用于样式控制 -->
    <div class="button-container">
        <button class="button" id="studentPicker">随机点名</button>
    </div>
</div>
<script>
    // 定义了方法
    function initStudentPicker() {
        console.log("initStudentPicker()");

        class StudentPicker {
            constructor(config) {
                this.studentTableBody = document.getElementById('studentTableBody');
                this.studentNameElement = document.getElementById('studentName');
                this.studentNames = config.students;

                // this.cellWidth = config.cellWidth || '100px';
                // this.cellHeight = config.cellHeight || '50px';
                // this.callCount = config.callCount || 10;
                // this.pickRandomStudentDelay = config.pickRandomStudentDelay || 200;

                // 默认宽度
                Object.defineProperty(this, 'cellWidth', {
                    value: config.cellWidth || '100px',
                    writable: false,
                    configurable: false
                });

                // 默认高度
                Object.defineProperty(this, 'cellHeight', {
                    value: config.cellHeight || '50px',
                    writable: false,
                    configurable: false
                });

                // 默认选择次数
                Object.defineProperty(this, 'callCount', {
                    value: config.callCount || 10,
                    writable: false,
                    configurable: false
                });

                // 每次选择时间间隔
                Object.defineProperty(this, 'pickRandomStudentDelay', {
                    value: config.pickRandomStudentDelay || 200,
                    writable: false,
                    configurable: false
                });


                this.generateStudentTable(this.studentTableBody, this.studentNames);
            }

            generateStudentTable(studentTableBody, studentNames) {
                studentTableBody.innerHTML = '';
                const columnsPerRow = 8;
                const rowCount = Math.ceil(studentNames.length / columnsPerRow);

                Array.from({ length: rowCount }).forEach((_, rowIndex) => {
                    const row = document.createElement('tr');

                    Array.from({ length: columnsPerRow }).forEach((_, colIndex) => {
                        const cellName = document.createElement('td');
                        const index = rowIndex * columnsPerRow + colIndex;

                        if (index < studentNames.length) {
                            cellName.textContent = studentNames[index];
                            cellName.classList.add('normal');
                            // 动态设置单元格的宽度和高度
                            cellName.style.width = this.cellWidth;
                            cellName.style.height = this.cellHeight;
                        }

                        row.appendChild(cellName);
                    });

                    studentTableBody.appendChild(row);
                });
            }

            pickRandomStudent(studentNameElement) {
                const nonEmptyStudents = this.studentNames.filter(name => name.trim() !== '');

                if (nonEmptyStudents.length === 0) {
                    console.warn('没有有效的学生姓名可供选择');
                    return;
                }


                // 缓存表格单元格
                const cells = Array.from(this.studentTableBody.getElementsByTagName('td'));
                // 随机数的生成范围(在此范围)
                const randomIndex = Math.floor(Math.random() * nonEmptyStudents.length);
                const randomStudent = nonEmptyStudents[randomIndex];

                studentNameElement.textContent = randomStudent;
                studentNameElement.style.opacity = 1;

                cells.forEach(cell => {
                    const isSelected = cell.textContent === randomStudent;
                    cell.classList.toggle('selected', isSelected); // 添加或移除 selected 类
                    cell.classList.toggle('normal', !isSelected); // 添加或移除 normal 类
                });
            }

            handleOnclick(buttonItem) {
                console.log("handleOnclick()");

                // 获取当前对象
                const button = buttonItem;

                // 判断是否是 HTML 元素
                if (!(buttonItem instanceof HTMLElement)) {
                    console.error('buttonItem 不是一个 HTML 元素');
                    return;
                }

                const self = this; // 将 this 赋值给 self
                const studentNameElement = this.studentNameElement;
                const delayTime = this.pickRandomStudentDelay;

                async function delay(ms) {
                    return new Promise((resolve) => setTimeout(resolve, ms));
                }


                // 使用闭包避免共享变量
                const runTask = async () => {
                    // console.log('runTask 中的 button:', button); // 验证 button 是否有效
                    for (let callCount = 0; callCount < self.callCount; callCount++) {
                        self.pickRandomStudent(studentNameElement);
                        await delay(delayTime); // 等待指定的时间
                    }

                    // 启用按钮并移除禁用样式
                    button.disabled = false;
                    button.classList.remove('disabled'); // 移除禁用样式
                };

                // 禁用按钮并设置禁用样式
                button.disabled = true;
                button.classList.add('disabled'); // 添加禁用样式
                console.log("handleOnclick() add success!");
                runTask();
            }

        }

        /**
         * 学生数据
         * @type {{students: string[], cellWidth: string, cellHeight: string}}
         */
        const config = {
            students: [
                '张三', '李四', '王五', '赵六', '孙七', '周八', '吴九', '郑十', '钱十一', '王十二',
                '李十三', '周十四', '吴十五', '郑十六', '钱十七', '王十八', '李十九', '周二十', '吴二十一', '郑二十二',
                '钱二十三', '王二十四', '李二十五', '周二十六', '吴二十七', '郑二十八', '钱二十九', '王三十', '李三十一', '周三十二',
                '吴三十三', '郑三十四', '钱三十五', '王三十六', '李三十七', '周三十八', '吴三十九', '郑四十', '钱四十一', '王四十二',
                '李四十三', '周四十四', '吴四十五', '郑四十六', '钱四十七', '王四十八', '李四十九'
            ],
            cellWidth: '120px', // 配置单元格宽度
            cellHeight: '60px',  // 配置单元格高度
            callCount: 20,  // 【5-20】这个范围比较合适
            pickRandomStudentDelay: 150  // 200ms 到 500ms 是一个比较合适的范围，既能保证用户看清选中了谁，又不会让用户觉得等待 （315黄金分割）
        };

        const studentPicker = new StudentPicker(config);
        const pickerButton = document.getElementById('studentPicker');
        pickerButton.addEventListener('click', () => {
            studentPicker.handleOnclick(pickerButton);
        });
    }


    // window.onload = function () {
    //     console.log("onload");
    //     initStudentPicker();
    // }

    // 加载后代码直接执行
    document.addEventListener('DOMContentLoaded', () => {
        console.log("DOMContentLoaded");
        initStudentPicker();
    });
</script>
</body>
</html>